<template>
  <div class="dept-list">
    <div class="dept-list__top">
      <span>组织架构</span>
      <ul>
        <li>
          <el-tooltip content="刷新" placement="bottom">
            <el-icon @click="refresh"><Refresh /></el-icon>
          </el-tooltip>
        </li>
        <li>
          <el-tooltip content="拖拽排序" placement="bottom">
            <el-icon @click="isDrag = true"><Operation /></el-icon>
          </el-tooltip>
        </li>
        <li v-show="isDrag">
          <el-button @click="handleOrder(true)">保存</el-button>
        </li>
        <li v-show="isDrag">
          <el-button @click="handleOrder(false)">取消</el-button>
        </li>
      </ul>
    </div>
    <div class="dept-list__body" @contextmenu.prevent="handleContextMenu">
      <el-scrollbar height="200">
        <el-tree
          ref="treeRef"
          :data="treeData"
          :props="{ label: 'name' }"
          :expand-on-click-node="false"
          :draggable="isDrag"
          :allow-drag="allowDrag"
          :allow-drop="allowDrop"
          default-expand-all
          node-key="id"
          @node-click="handleNodeClick"
          @node-contextmenu="handleContextMenu"
        />
      </el-scrollbar>
    </div>
  </div>

  <ContextMenu ref="contextMenuRef" />
</template>

<script>
import { departmentOrder, getSysDeptList } from "@/api/sys";
import { listToTree } from "@/utils/common";
import ContextMenu from "@/components/context-menu/index.vue";
import { ElMessage, ElMessageBox } from "element-plus";

export default {
  name: "DeptList",

  components: { ContextMenu },

  emits: ["change"],

  data() {
    return {
      isDrag: false, // 是否排序
      currentNodeKey: 1,
      list: [],
    };
  },

  computed: {
    treeData() {
      return listToTree(this.list);
    },
  },

  methods: {
    async refresh() {
      // 获取部门列表数据
      this.list = await getSysDeptList();

      if (this.currentNodeKey === -1) {
        // 获取顶级的节点Id
        this.currentNodeKey = this.list.filter((item) => !item.parentId)[0].id;
      }

      this.$nextTick(() => {
        // 调用 setCurrentKey 将其选择
        this.$refs.treeRef.setCurrentKey(this.currentNodeKey);

        // 手动调用一次 handleNodeClick
        this.handleNodeClick();
      });
    },

    // 单个节点点击事件
    handleNodeClick(data) {
      if (!data) {
        data = this.treeData[0];
      }
      // console.log("data", data);
      this.currentNodeKey = data.id;
      // 计算当前节点已经子节点的id集合
      const ids = [data.id];

      function deep(arr) {
        arr.forEach((item) => {
          ids.push(item.id);

          if (item.children && item.children.length > 0) {
            deep(item.children);
          }
        });
      }
      if (data.children && data.children.length > 0) {
        deep(data.children);
      }

      // 触发一个change事件
      this.$emit("change", {
        ids,
        name: data.name,
      });
    },

    // 节点右键点击
    handleContextMenu(event, data) {
      if (!data) {
        data = this.list[0];
      }

      console.log("data", data);

      const menuItems = [
        {
          index: 1,
          label: "新增",
          action: () => {
            console.log("点击了 新增");
          },
        },
        {
          index: 2,
          label: "编辑",
          action: () => {
            console.log("点击了 编辑");
          },
        },
        {
          index: 4,
          label: "新增成员",
          action: () => {
            console.log("点击了 新增成员");
          },
        },
      ];

      if (data.parentId) {
        menuItems.splice(2, 0, {
          index: 3,
          label: "删除",
          action: () => {
            console.log("点击了 删除");
          },
        });
      }

      this.$refs.contextMenuRef.open(event, menuItems);
    },

    // 控制拖的规则，不为顶级的就可以拖拽
    allowDrag(node) {
      // return node.data.name !== "测试";
      return node.level !== 1;
    },

    // 控制放的规则，不能与顶级同级
    allowDrop(dragNode, dropNode, type) {
      if (dropNode.level === 1) {
        return type === "inner";
      } else {
        return true;
      }
    },

    // 排序
    handleOrder(bol) {
      if (!bol) {
        // 取消
        this.isDrag = false;
        this.refresh();
        return;
      }

      // 保存
      ElMessageBox.confirm("部门架构已发生改变，是否保存？", "提示", {
        type: "warning",
      }).then(() => {
        const ids = [];

        // 修改数组中每一项的 parentId
        function deep(list, pid) {
          list.forEach((item) => {
            item.parentId = pid;

            ids.push(item);

            if (item.children && item.children.length > 0) {
              deep(item.children, item.id);
            }
          });
        }

        deep(this.treeData, null);
        // 将 ids 转换成接口需要的数据格式
        const params = ids.map((item, index) => ({
          id: item.id,
          parentId: item.parentId,
          orderNum: index,
        }));

        console.log("params", params);
        //   调用接口
        departmentOrder(params).then((result) => {
          ElMessage.success("更新排序完成");
          this.isDrag = false;
          this.refresh();
        });
      });
    },
  },

  created() {
    this.refresh();
  },
};
</script>

<style scoped>
.dept-list {
  width: 300px;
  background-color: antiquewhite;
}
.dept-list__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  height: 40px;
}

.dept-list__body {
  padding: 10px 5px;
}

:deep(.el-tree-node__content) {
  height: 36px;
}

:deep(.is-current > .el-tree-node__content) {
  color: #4165d7;
  background-color: pink;
}

.dept-list__top ul {
  list-style: none;
  display: flex;
}
.dept-list__top ul li {
  display: inline-flex;
  align-items: center;
  margin-left: 5px;
  padding: 5px;
  height: 34px;
  cursor: pointer;
}
.dept-list__top ul li:hover {
  background-color: green;
}
</style>
